package dataformat

import (
	"net"
)

func IsPrivateIP(ipStr string) bool {
	ip := net.ParseIP(ipStr)

	return ip != nil && ip.IsPrivate()
}

func IsPrivateIPv4(ipStr string) bool {
	ip := net.ParseIP(ipStr)
	return IsIPv4(ipStr) && ip.IsPrivate()
}

func IsPrivateIPv6(ipStr string) bool {
	ip := net.ParseIP(ipStr)
	return IsIPv6(ipStr) && ip.IsPrivate()
}

func IsPublicIP(ipStr string) bool {
	ip := net.ParseIP(ipStr)
	if ip == nil || ip.String() == "0.0.0.0" || ip.String() == "255.255.255.255" || ip.String() == "::" {
		return false
	} else if ip.IsLoopback() || ip.IsMulticast() || ip.IsLinkLocalUnicast() {
		return false
	}
	return !IsPrivateIP(ipStr)
}

func IsPublicIPv4(ipStr string) bool {
	return IsIPv4(ipStr) && IsPublicIP(ipStr)
}

func IsPublicIPv6(ipStr string) bool {
	return IsIPv6(ipStr) && IsPublicIP(ipStr)
}

func IsIP(ipStr string) bool {
	ip := net.ParseIP(ipStr)

	return ip != nil
}

func IsIPv4(ipStr string) bool {
	ip := net.ParseIP(ipStr)

	return ip != nil && ip.To4() != nil
}

func IsIPv6(ipStr string) bool {
	ip := net.ParseIP(ipStr)

	return ip != nil && ip.To16() != nil && ip.To4() == nil
}

func IsCIDR(s string) bool {
	ip, ipnet, err := net.ParseCIDR(s)
	return err == nil && ipnet.IP.Equal(ip)
}

func IsCIDRv4(s string) bool {
	ip, ipnet, err := net.ParseCIDR(s)
	return err == nil && ipnet.IP.Equal(ip) && ip.To4() != nil
}

func IsCIDRv6(s string) bool {
	ip, ipnet, err := net.ParseCIDR(s)
	return err == nil && ipnet.IP.Equal(ip) && ip.To16() != nil
}
